R ile Büyük Veri Üzerinde Çalışma, Görselleştirme ve Modelleme
1. Önsöz
MARMARA ÜNİVERSİTESİ
FEN-EDEBİYAT FAKÜLTESİ İSTATİSTİK BÖLÜMÜ
ARAŞTIRMA PROJESİ
Danışman: Müjgan TEZ
1.1 Amaç
BÜYÜK VERİ ile çalışmak, belirli veri analizi araçları, paketleri ve makine öğrenimi gibi gelişmiş teknikler gerektirir. Bu çalışma, büyük verileri keşfetmek, görselleştirmek, ve modellemek için R içerisinde bulunan araçların ve makine öğrenimi yöntemlerinin kullanımına ilişkin uygulamalı bir eğitim olacaktır.
Çalışmamız, lisans eğitimi boyunca öğrendiklerimiz ve bu konu üzerinde geliştirme amacıyla yaptığımız çalışmalarımızın bir çıktısıdır.
1.2 Proje Üyeleri
Tarık ÇELİK
Enes Malik DİCLE
Gizem ATEŞ
Yaren DEMİRBAŞ
2. Giriş
2.1 Büyük Veri Nedir?
Büyük veri; verinin analiz edilip sınıflandırılmış, anlamlı ve işlenebilir hale dönüştürülmüş halidir. Yükselen teknolojiler ve tüketicilerin artan veri kullanım oranı paralelinde daha fazla çeşitlilik içeren veri kümesidir.
Büyük verinin 3 karakteristik özelliği olan İngilizce’deki variety, velocity ve volume kelimelerinden türeyen 3V kavramıdır. Büyük veriyi daha iyi anlamamıza yardımcı olurlar.
Çeşitlilik (Variety): Büyük veri çeşitliliği yapılan sorgularda daha eksiksiz cevap almaya yarar. Çünkü veriler metin belgelerinden e-postalara, sayısal verilerden, videolara, seslere, finansal işlemlere kadar her türlü farklı formatlardan derlenebilir.
Hız (Velocity): Gerçek zamanlı veri oluşturulma hızını ifade etmektedir. Daha geniş bir bakışla, değişim oranını, gelen veri setlerinin değişen hızlarda bağlanmasını ve etkinlik patlamalarını içerir.
Hacim (Volume): Adından da anlaşıldığı gibi büyük verinin günlük bazda oluşturulan devasa bilgi setleri olduğunu biliyoruz. Bu kaynaklar sosyal medya, iş süreçleri, makineler, ağlar, veya insan etkileşimleri olabilir.
Şekil 2.1: Büyük Veride 3V
2.2 Büyük Veri Neden Önemlidir?
Big Data ne kadar bilgi sahibi olunduğundan ziyade onunla ne yapılacağı üzerine yoğunlaşıyor. Herhangi bir kaynaktan veri alıp onları para ve zaman tasarrufu (maliyet azaltma), yeni proje, ürün, hizmet gelişimi ve optimize edilmiş önerileri aynı zamanda da akıllı karar verilmesini sağlayan cevaplar bulmak için analiz edebilirsiniz. Büyük veri güçlü analizlerle birleştiğinde iş ile alakalı şunlar gerçekleştirilebilir:
- Gerçek zamanlı hata ve sorunların temel nedenlerini belirleme.
- Müşterilerin satın alma alışkanlıklarına dayanarak satış amaçlı kuponlar üretme.
- Yeni portfolyoların risklerini tekrar hesaplama.
- İşleyişi etkilemeden önce yanlış davranışları tespit etme.
Büyük verilerin önemi, sahip olduğunuz verinin ne olduğu, ne yaptığınızla ilgili değildir.
2.3 Büyük Verinin Çalışması için Üç Yöntem
Strateji 1: Örnek ve Model
Örneklemek ve modellemek için, verilerimizi tümüyle kolayca indirilebilecek bir boyuta küçültürüz ve örnek üzerinde bir model oluştururuz. Binlerce, hatta yüzbinlerce veri noktasına alt örnekleme, model çalışma sürelerini de istatistiksel geçerliliğini korurken mümkün kılar.
Sınıf dengesini korumak gerekiyorsa (veya bir sınıfın fazla / az örneklenmesi gerekiyorsa), örnekleme sırasında veri kümesini sınıflandırmak oldukça basittir.
Şekil 2.3: Örneklem
Avantajları
- Hız: Tüm veri kümemiz üzerinde çalışmaya kıyasla, sadece bir örnek üzerinden çalışmak; çalışma sürelerini önemli ölçüde azaltabilir ve yineleme hızını artırabilir.
- Prototipleme (İlk örnekleme): Sonunda modelimizi tüm veri kümesinde çalıştırmak zorunda kalsak bile, bu hiperparametreleri hassaslaştırmak ; modelimiz için iyi bir yol olabilir.
- Paketler: Normal bir bellek içi veri kümesi üzerinde çalıştığımızdan, istediğimiz tüm R paketlerini kullanabiliriz.
Dezavantajları
- Örnekleme: Alt örnekleme zor değildir, ancak geçerli olduğundan ve orijinal veri kümesinden yeterli sayıda nokta aldığımızdan emin olmak için dikkatle yapılması gerekir.
- Ölçekleme: Daha sonra tam veri kümesinde çalıştırılacak bir şeyi prototiplemek için örnek ve model kullanıyorsak, prototip sürümümüzü tekrar tam veriye ölçeklendirmek için bir stratejimiz olması gerekir (veriyi hesaplamaya itmek gibi)
- Toplam: İş Zekası (BI) görevleri, bir aydaki tüm satışların sayısı gibi, toplamlar hakkındaki soruları sık sık yanıtlar. Diğer stratejilerden biri, bu durumda genellikle daha iyi bir seçimdir.
Strateji 2: MapReduce
Bu stratejide, veriler ayrılabilir birimlere yığınlanır ve her yığın ayrı ayrı çekilir ve seri, paralel veya yeniden birleştirmeden sonra çalıştırırız. Bu strateji kavramsal olarak MapReduce algoritmasına benzer. Eldeki işe bağlı olarak, parçalar zaman periyotları, coğrafi birimler veya ayrı işletmeler, departmanlar, ürünler veya müşteri segmentleri gibi mantıklı olabilir.
Şekil 2.3: Mapreduce
Avantajları
- Tam veri kümesi: Veri kümesinin tamamını kullanırız.
- Paralelleştirme: Eğer parçaları ayrı ayrı çalıştırırsak, sorunu kapsamlı bir şekilde paralel olarak ele alabiliriz ve çalışma zamanlarını hızlandırmak için paralelleştirmeyi kullanırız.
Dezavantajları
- Gerekli Parçalar: Veri ve yığının uygun olması için ayrılabilir parçalara sahip olmamız gerekir.
- Tüm Verileri Çekmek: Belleğin yoğun olabileceği durumlarda tüm verierimizi çekmek zorunda kalırız.
- Eski Veriler: Yerel makinemize bir sürüm kaydettiğimizden, güncel kalması için verilerimizin periyodik olarak yenilenmesi gerekebilir.
Strateji 3: Hesaplamayı Verilere Aktarma
Bu stratejide, verileri veritabanında sıkıştırırız ve yalnızca sıkıştırılmış veri kümesi veritabanından R‘a taşınır. Verileri R‘a çekmeden önce veritabanında özetleme veya filtreleme yaparak hızlandırmalar elde etmemiz genellikle mümkündür.
Bazen, dbplot ile histogram ve raster haritalarını hesaplama, modeldb ile bir model oluşturma ve tidypredict ile makine öğrenme modellerinden tahminler oluşturma gibi daha karmaşık işlemler de mümkündür.
Şekil 2.3: Sıkıştırma
Avantajları
- Veritabanını Kullanma: En iyi veritabanlarının avantajlarından yararlanırız. (Bir sorguyu temel alarak verileri hızlı bir şekilde özetleme ve filtreleme gibi.)
- Daha Fazla Bilgi, Daha Az Aktarım: Verileri tekrar R‘a çekmeden önce sıkıştırarak, tüm veri kümesini kullanırız. Ancak aktarım süreleri tüm veri kümesini taşımaktan çok daha azdır.
Dezavantajları
- Veritabanı İşlemleri: Hangi veritabanını kullandığımıza bağlı olarak, bazı işlemler desteklenmiyor olabilir.
- Veritabanı Hızı: Bazı bağlamlarda, veri analizi için sınırlayıcı faktör veritabanının hızıdır ve bu nedenle veritabanına daha fazla iş eklemek analistlerin yapmak istediği son şeydir.
2.4 Veri Seti
data=read.csv("C:/Users/emali/Desktop/cardio.csv",sep=";")
data=data[,-1] #ID değişkeni çıkarıldı.Kaynak: https://www.kaggle.com/sulianova/cardiovascular-disease-dataset
Veri: Kardiyovasküler Hastalık veri setidir. Veri seti, 70.000 hasta verisi kaydı, 12 değişkenden oluşur. Tüm veri seti değerleri tıbbi muayene anında toplanmıştır.
| Değişken Adı | Açıklaması | Değişken Türü |
|---|---|---|
| age | Yaş | Numerik |
| gender | Cinsiyet | 1:Kadın ; 2:Erkek |
| height | Boy (cm) | Numerik |
| weight | Ağırlık (kg) | Numerik |
| ap_hi | Büyük Tansiyon | Numerik |
| ap_lo | Küçük Tansiyon | Numerik |
| cholesterol | Kolestrol | 1:Normal ; 2:Normalin Üstünde ; 3:Normalin Çok Üstünde |
| gluc | Glukoz Seviyesi | 1:Normal ; 2:Normalin Üstünde ; 3:Normalin Çok Üstünde |
| smoke | Sigara İçme Durumu | 1:Sigara İçen ; 0:Sigara İçmeyen |
| alco | Alkol Kullanım Durumu | 1:Alkol İçen ; 0:Alkol İçmeyen |
| active | Aktiflik Durmu | 1:Aktif ; 0:Aktif Değil |
| cardio | Hastalık Durumu | 1:Var ; 0:Yok |
2.4.1 Veri Setini Düzenleme
#Age
data$age=data$age/365
data$age=round(data$age,digits=0)
#Yaş değişkeni 365 ile bölünerek yıl olarak hesaplandı ve küsüratlar ortadan kaldırıldı.
#Bmi(Yeni Degisken)
data$bmi=data$weight/((data$height/100)^2)
#Gender
data$gender[data$gender==1]<-"Kadin"
data$gender[data$gender==2]<-"Erkek"
#Cholesterol
data$cholesterol[data$cholesterol==1]<-"Normal"
data$cholesterol[data$cholesterol==2]<-"Normalin Ustunde"
data$cholesterol[data$cholesterol==3]<-"Normalin Cok Ustunde"
#Glucose
data$gluc[data$gluc==1]<-"Normal"
data$gluc[data$gluc==2]<-"Normalin Ustunde"
data$gluc[data$gluc==3]<-"Normalin Cok Ustunde"
#Smoke
data$smoke[data$smoke==0]<-"Sigara icmeyen"
data$smoke[data$smoke==1]<-"Sigara icen"
#Alcohol
data$alco[data$alco==0]<-"Alkol icmeyen"
data$alco[data$alco==1]<-"Alkol icen"
#Active
data$active[data$active==0]<-"Aktif Degil"
data$active[data$active==1]<-"Aktif"
#Cardio
data$cardio[data$cardio==0]<-"Yok"
data$cardio[data$cardio==1]<-"Var"Değişkenler üzerinde gerekli düzenlemeler yapıldı.
BMI (vücut kitle indeksi) adında yeni bir değişken eklendi.
data$gender<-as.factor(data$gender)
data$cholesterol<-as.factor(data$cholesterol)
data$gluc<-as.factor(data$gluc)
data$smoke<-as.factor(data$smoke)
data$alco<-as.factor(data$alco)
data$active<-as.factor(data$active)
data$cardio<-as.factor(data$cardio)Gerekli değişkenler faktör olarak atandı.
plot_missing(data)Eksik gözlemleri kontrol ettiğimizde, veride herhangi bir eksik gözlem olmadığını gördük.
2.4.2 Veriyi Özetlemek
head(data) age gender height weight ap_hi ap_lo cholesterol gluc
1 50 Erkek 168 62 110 80 Normal Normal
2 55 Kadin 156 85 140 90 Normalin Cok Ustunde Normal
3 52 Kadin 165 64 130 70 Normalin Cok Ustunde Normal
4 48 Erkek 169 82 150 100 Normal Normal
5 48 Kadin 156 56 100 60 Normal Normal
smoke alco active cardio bmi
1 Sigara icmeyen Alkol icmeyen Aktif Yok 21.96712
2 Sigara icmeyen Alkol icmeyen Aktif Var 34.92768
3 Sigara icmeyen Alkol icmeyen Aktif Degil Var 23.50781
4 Sigara icmeyen Alkol icmeyen Aktif Var 28.71048
5 Sigara icmeyen Alkol icmeyen Aktif Degil Yok 23.01118
[ reached 'max' / getOption("max.print") -- omitted 1 rows ]
str(data)'data.frame': 70000 obs. of 13 variables:
$ age : num 50 55 52 48 48 60 61 62 48 54 ...
$ gender : Factor w/ 2 levels "Erkek","Kadin": 1 2 2 1 2 2 2 1 2 2 ...
$ height : int 168 156 165 169 156 151 157 178 158 164 ...
$ weight : num 62 85 64 82 56 67 93 95 71 68 ...
$ ap_hi : int 110 140 130 150 100 120 130 130 110 110 ...
$ ap_lo : int 80 90 70 100 60 80 80 90 70 60 ...
$ cholesterol: Factor w/ 3 levels "Normal","Normalin Cok Ustunde",..: 1 2 2 1 1 3 2 2 1 1 ...
$ gluc : Factor w/ 3 levels "Normal","Normalin Cok Ustunde",..: 1 1 1 1 1 3 1 2 1 1 ...
$ smoke : Factor w/ 2 levels "Sigara icen",..: 2 2 2 2 2 2 2 2 2 2 ...
$ alco : Factor w/ 2 levels "Alkol icen","Alkol icmeyen": 2 2 2 2 2 2 2 2 2 2 ...
$ active : Factor w/ 2 levels "Aktif","Aktif Degil": 1 1 2 1 2 2 1 1 1 2 ...
$ cardio : Factor w/ 2 levels "Var","Yok": 2 1 1 1 2 2 2 1 2 2 ...
$ bmi : num 22 34.9 23.5 28.7 23 ...
summary(data) age gender height weight
Min. :30.00 Erkek:24470 Min. : 55.0 Min. : 10.00
1st Qu.:48.00 Kadin:45530 1st Qu.:159.0 1st Qu.: 65.00
Median :54.00 Median :165.0 Median : 72.00
Mean :53.34 Mean :164.4 Mean : 74.21
3rd Qu.:58.00 3rd Qu.:170.0 3rd Qu.: 82.00
ap_hi ap_lo cholesterol
Min. : -150.0 Min. : -70.00 Normal :52385
1st Qu.: 120.0 1st Qu.: 80.00 Normalin Cok Ustunde: 8066
Median : 120.0 Median : 80.00 Normalin Ustunde : 9549
Mean : 128.8 Mean : 96.63
3rd Qu.: 140.0 3rd Qu.: 90.00
gluc smoke alco
Normal :59479 Sigara icen : 6169 Alkol icen : 3764
Normalin Cok Ustunde: 5331 Sigara icmeyen:63831 Alkol icmeyen:66236
Normalin Ustunde : 5190
active cardio bmi
Aktif :56261 Var:34979 Min. : 3.472
Aktif Degil:13739 Yok:35021 1st Qu.: 23.875
Median : 26.374
Mean : 27.557
3rd Qu.: 30.222
[ reached getOption("max.print") -- omitted 1 row ]
3. Veriyi Okutma Teknikleri
3.1 data.frame Nedir?
Data.frame işlevi, R’ın modelleme yazılımının temel veri yapısı olarak kullanılan, matrislerin ve listelerin birçok özelliğini paylaşan, bağlı değişken koleksiyonları barındıran veri grupları oluşturmaya yarar. Data Frame’ler, tablo halinde verileri R’de saklamak için kullanılır. Bunlar, R’daki önemli nesne türlerinden biridir ve çeşitli istatistiksel modelleme uygulamalarında kullanılır. Data Frame’ler genellikle bir veri setinden(excel veya csv) read.table () veya read.csv () fonksiyonları kullanılarak okunur ve oluşturulur. Bununla birlikte, Data Frame’ler, data.frame () fonksiyonu ile açıkça oluşturulabilir. Veri çerçevesi, her sütunun bir değişkenin değerlerini ve her satırın her sütundan bir değer kümesini içerdiği bir tablo veya iki boyutlu dizi benzeri bir yapıdır.
Aşağıda bir veri çerçevesinin özellikleri verilmiştir.
- Sütun adları boş olmamalıdır.
- Satır adları benzersiz olmalıdır.
- Bir veri çerçevesinde saklanan veriler sayısal, faktör veya karakter tipinde olabilir.
- Her sütun aynı sayıda veri öğesi içermelidir.
3.2 data.table Nedir?
data.table, R tabanında veri depolamak için standart veri yapısı olan data.frame’in gelişmiş bir sürümünü sağlayan bir R paketidir. Data.frame’in aksine, karakter türündeki sütunlar hiçbir zaman varsayılan olarak faktörlere dönüştürülmez. Bu kadar popüler olmasının nedeni, daha büyük veriler üzerinde yürütme hızı ve kısa sözdizimidir. Böylece etkili bir şekilde daha az kod yazılır ve çok daha hızlı işlemler uygulanır. Data.table, data.frame’den biraz farklı bir sözdizimi sağlasa da, oldukça sezgiseldir.
3.3 data.table ve data.frame Hız Testi
set.seed(100)
m <- data.frame(matrix(runif(10000000), nrow=1000000))
write.csv(m, 'm2.csv', row.names = F)
(data_frame=system.time({m_df <- read.csv('m2.csv')})) user system elapsed
40.46 0.98 41.90
(data_table=system.time({m_dt <- fread('m2.csv')})) user system elapsed
0.53 0.14 0.40
Çekilen iki rastgele örneklemde performans süreleri hesaplanmıştır. Data table üzerindeki performansın daha etkili olduğu görülmektedir. Baz alınan süreler arasındaki fark dosya büyüklüğü ile doğru oranda artış gösterecektir.
3.4 dplyr vs data.table
Data.table ve dplyr, her ikisi de veri çerçevelerinin daha kolay ve verimli bir şekilde değiştirilmesini amaçlayan iki R paketidir. Ancak birçok işlevi ortak olsada, felsefeleri oldukça farklıdır. Data.table birçok işlemi çok kısa ve tutarlı bir ifadede birleştirmeye izin verir. dplyr en yaygın işlemlere karşılık gelen anahtar fiillere dayanmaktadır. data.table paketinin bağımlılığı yoktur, oysa dplyr tidyverse’in bir parçasıdır. Örneğin, data.table verileri okuma, yazma veya yeniden şekillendirme işlevlerini içerirken, dplyr bu görevleri readr veya tidyr gibi tamamlayıcı paketlere devreder. Öte yandan, data.table yerel bellek içi verilerin işlenmesine odaklanır, ancak dplyr bir veritabanı arka ucu sunar. data table‘da nesneler “referans olarak” değiştirilebilir. Bu, verilerin değiştirileceği ancak kopyalanmayacağı anlamına gelir, bu da RAM gereksinimlerini en aza indirir. Dplyr’da ise, bellek yönetimi, paralellik ve optimizasyon, data.table’a performans açısından avantaj sağlar.
data.table’ın yazarı Matt Dowle:
“data.table, kullanım kolaylığı, rahatlık ve programlama hızı için sözdizimi ve özellik geliştirmeleri ile R’ın veri çerçevesinin yüksek performanslı bir sürümünü sağlar.”
dplyr’ın yazarı Hadley Wickham:
“dplyr, en yaygın veri işleme zorluklarını çözmenize yardımcı olan tutarlı bir fiil kümesi sağlayan bir veri işleme dilbilgisidir.”
3.4.1 dplyr vs data.table Uygulama
data("AutoClaims") #veri setinin yüklenmesi
db <- AutoClaims #veri setine yeni bir isim atanması
db <- data.table(db) #data.table'a dönüştürmeVerinin 6773 satırı ve 5 sütunu vardır.
head(db) STATE CLASS GENDER AGE PAID
1: STATE 14 C6 M 97 1134.44
2: STATE 15 C6 M 96 3761.24
3: STATE 15 C11 M 95 7842.31
4: STATE 15 F6 F 95 2384.67
5: STATE 15 F6 M 95 650.00
6: STATE 15 F6 M 95 391.12
3.4.2 En Sık Kullanılan 10 Veri İşleme İşlevi
- Satırlara Göre Filtrelemek
79 yaş ve altı erkekler için filtre uygulandı.
# db[AGE <= 79 & GENDER == "M"] #datatable
# db %>% filter(AGE <= 79 & GENDER == "M") #dplyr- Sütunlara Göre Seçim Yapmak
GENDER, AGE ve PAID sütunlarını seçelim.
# db[, .(GENDER, AGE, PAID)] #datatable
# db %>% select(GENDER, AGE, PAID) #dplyr- Yeni Sütunlar Eklemek
8,63 Dolar/TL dönüşüm oranını kullanarak PAID’yi Dolardan TL’ye çevirelim. Ortaya çıkan yeni değişken veri kümesine eklenir.
# db[, PAID.IN.TL := PAID * 8.63] #datatable
# db %>% mutate(PAID.IN.TL = PAID * 8.63) #dplyr- Sütun Silmek
Yeni oluşturulan değişkeni silelim.
# db[, !c("PAID.IN.TL")] #datatable
# db[, PAID.IN.TL := NULL] #datatable (alternatif yol)
# select(db, -PAID.IN.TL) #dplyr- Yeni Sütun Oluşturmak
Yeni bir değişken oluşturup ve mevcut olanları bırakalım. Sonuç olarak, veri kümesi yalnızca yeni bir değişkene sahip olacaktır.
# db[, .(PAID.IN.TL = PAID * 8.63)] #datatable
# db %>% transmute(PAID.IN.TL = PAID * 8.63) #dplyr- Sütuna Göre Özetlemek
Ödenen ortalama sigorta tazminatı ne kadardır? Aşağıdaki kod verileri toplar ve AVG.PAID adlı tek bir kayıt döndürür.
# db[, .(AVG.PAID = mean(PAID))] #datatable
# db %>% summarise(AVG.PAID = mean(PAID)) #dplyr- Değişkeni Yeniden Adlandırmak
“data.table” ile eski isimleri ve ardından yeni isimleri referans alan “setnames” fonksiyonunu kullanırız. “dplyr” ile sıra tersine çevrilir.
# setnames(db, c("GENDER", "CLASS"), c("gender", "class")) #dt
# db %>% rename("gender" = "GENDER", "class" = "CLASS") #dplyr- Verileri Artan Veya Azalan Düzende Sıralamak
data.table’daki “setorder” ve dplyr’daki “arrange” işlevini kullanarak verileri artan ve azalan düzende sıralayabiliriz.
# setorder(db, PAID) #datatable artan sıralama
# setorder(db, -PAID) #datatable azalan sıralama
# db %>% arrange(PAID) #dplyr artan sıralama
# db %>% arrange(desc(PAID)) #dplyr azalan sıralama- Sütuna Göre Gruplandırmak
Verileri tek başına gruplamak hiçbir anlam ifade etmez; bunu başka bir işlevle birleştirmelisiniz. Örneğin “State” değişkenine göre gruplandırmalı ve verileri özetlemeli veya verileri filtrelemelisiniz.
# db[, .(mean.paid.by.state = mean(PAID)), by = "STATE"]
# db %>% group_by(STATE) %>%
# summarize(mean.paid.by.state = mean(PAID))- Gözlemleri Saymak
dplyr için “n()” işlevini ve data.table için “.N” işlevini kullanarak her sınıf için kaç gözlemimiz olduğunu sayabiliriz.
# db[, .N, by= "class"] #datatable
# db %>% #dplyr
# group_by(class) %>%
# summarise(n())dplyr ve data.table karşılaştırıldı. 10 ortak işlev ve zincirleme işlevler kullandık. Her iki kütüphaneyle de yapabilecek çok işlem mevcuttur. Data.table, dplyr’dan daha kısa sözdizimi kullanır, ancak genellikle daha ayrıntılı ve karmaşıktır. Bellek ve hız önemli mi? Karmaşık raporlar ve dashboardlar oluştururken ve özellikle çok büyük veri kümeleriyle çalışırken data.table’ın belirgin avantajları vardır.
3.5 Sparklyr Paketi
Sparklyr, “R” ve “Apache Spark” arasında bir arayüz sağlayan, R’daki büyük verileri işlemek için kullanılan açık kaynaklı küme hesaplama mantığında çalışan bir pakettir. Sparklyr kütüphanesi ile büyük veriyi bir Spark kümesi içerisinde analiz edebilirsiniz. Bu paket, hem bellekte hem de bellek dışında veri çerçevesi nesneleriyle çalışmak için popüler bir araç olan dplyr paketi için eksiksiz bir zemin oluşturmaktadır. R kodunu Spark SQL’e çevirmek için dplyr kullanabilirsiniz. Sparklyr ayrıca MLlib‘i destekler, böylece Spark’ta verileriniz üzerinde sınıflandırma, regresyon, küme, karar ağaçları ve daha birçok makine öğrenimi algoritmasını çalıştırabilirsiniz. MLlib, Apache Spark’ın ölçeklenebilir makine öğrenimi kütüphanesidir. Java, Scala, Python programlama dilllerinde de kullanılabilir. Sparklyr ile, geleneksel olarak R belleğini aşan büyük miktarda veriyi analiz edebilir, daha fazla görselleştirme ve dokümantasyon için Spark’tan R’a sonuçlar toplayabilirsiniz.
3.5.1 MapReduce ve Spark Karşılaştırması
Spark’ın ilk çıktığı zamanlarda Hadoop ile bolca karşılaştırılmış olsa da, ikisi birbirinden farklı teknolojilerdir. Spark’ın ana işlevi veri analizidir ve bir depolama birimi yoktur. Buna karşın Hadoop’un HDFS adı altında bir dosya sistemi, depolama birimi vardır. Hadoop veri analizi çözümü olan MapReduce’u da içeren geniş bir framework’tür.
MapReduce’da sadece HDFS dosya sisteminde yani disk üzerinde bulunan veri üzerinde analiz yapılabilirken Spark’ta HDFS dahil olmak üzere bir çok veri kaynağı (İlişkisel veritabanları, NoSql, Kafka, elasticsearch vb.) üzerinde analiz gerçekleştirilebilir. Spark bu analizleri yaparken ram üzerinde (in-memory) yapar, belleklerin yetmediği durumlarda diskleri de kullanır. Hızının sırrı da bellekleri kullanabilmesinde yatar. Bu yüzden Spark, Hadoop’tan 100 kat daha hızlı olduğunu iddia eder.
Spark, büyük veri ekosistemindeki birçok teknoloji gibi dağıtık mimariyi desteklediği için cluster’daki tüm sunucular üzerinde aynı anda dağıtık bir şekilde hesaplama yapar. Basit bir örnek verecek olursak cluster’ımızda her birinin 128GB ram’i olan 10 sunucumuz varsa, hesaplama yaparken 1 TB’ın üzerinde bir ram gücünü kullandığı anlamına gelir. Ram ile birlikte tüm bu sunucuların işlemci gücü de kullanılır. Spark’la birlikte kullanılan makine öğrenmesi algoritmaları için de geçerlidir bu hız. Mesela TensorFlow ve PyTorch gibi kütüphanelerle yazılan makine öğrenmesi algoritmaları tek bir ortamda çalıştırabilirken, Spark ile makine öğrenmesi uygulaması geliştirildiğinde tüm cluster’daki sunucularda çalıştırıldığı için daha hızlı olabilmektedir. Bu bağlamda Spark paralel işlem gücünü makine öğrenmesi alanına da uygulamıştır.
Sonuç
Apache Spark hem batch hem de real-time analize izin veren bunun yanı sıra makine öğrenmesi ve graf analizi ve sql gibi veriyle ilgili bir çok alanı destekleyen açık kaynak bir büyük veri aracıdır. Apache Spark bu kadar özelliğine rağmen rakipsiz değildir. Flink gibi güçlü rakipleri vardır. Arkasında güçlü bir topluluğun olmasıyla, birçok programlama diliyle analiz yapılabilmesiyle, streaming analizlerin öneminin her geçen gün artmasıyla ve makine öğrenmesi modülünün sürekli geliştirilmesiyle Apache Spark’ın sektördeki yeri sağlamlaşmaktadır.
3.5.2 Kurulum ve Spark Bağlantısının Oluşturulması
spark_install(version = "2.1.0")
sc <- spark_connect(master = "local", spark_home = spark_home_dir(version = "2.1.0"))Spark bağlantısını oluşturduk.
3.5.3 Verinin Spark’a Taşınması
src_tbls(sc)character(0)
Henüz Spark ortamına bir veri aktarmadık. Alınan çıktıda da bunu görüyoruz.
copy_to(sc, data , "cardio_spark")# Source: spark<cardio_spark> [?? x 13]
age gender height weight ap_hi ap_lo cholesterol gluc smoke alco active
<dbl> <chr> <int> <dbl> <int> <int> <chr> <chr> <chr> <chr> <chr>
1 50 Erkek 168 62 110 80 Normal Norm~ Siga~ Alko~ Aktif
2 55 Kadin 156 85 140 90 Normalin C~ Norm~ Siga~ Alko~ Aktif
3 52 Kadin 165 64 130 70 Normalin C~ Norm~ Siga~ Alko~ Aktif~
4 48 Erkek 169 82 150 100 Normal Norm~ Siga~ Alko~ Aktif
5 48 Kadin 156 56 100 60 Normal Norm~ Siga~ Alko~ Aktif~
6 60 Kadin 151 67 120 80 Normalin U~ Norm~ Siga~ Alko~ Aktif~
7 61 Kadin 157 93 130 80 Normalin C~ Norm~ Siga~ Alko~ Aktif
8 62 Erkek 178 95 130 90 Normalin C~ Norm~ Siga~ Alko~ Aktif
9 48 Kadin 158 71 110 70 Normal Norm~ Siga~ Alko~ Aktif
10 54 Kadin 164 68 110 60 Normal Norm~ Siga~ Alko~ Aktif~
# ... with more rows, and 2 more variables: cardio <chr>, bmi <dbl>
tbl_cachefunction (sc, name, force = TRUE)
{
countColumns <- function(sc, name) {
sql <- sprintf("SELECT * FROM %s LIMIT 0", tbl_quote_name(sc,
name))
sdf <- invoke(hive_context(sc), "sql", sql)
length(invoke(sdf, "columns"))
}
if (spark_version(sc) < "2.0.0" && countColumns(sc, name) >=
1000) {
tbl_cache_sdf(sc, name, force)
}
else {
tbl_cache_sql(sc, name, force)
}
invisible(NULL)
}
<bytecode: 0x0000000041d733d0>
<environment: namespace:sparklyr>
Spark ortamına veriyi tanıttık. Şimdi bir önceki chunkta uyguladığımız “src_tbls(sc)” kodunu bir kez daha çalıştırıp bunu görebiliriz.
src_tbls(sc)[1] "cardio_spark"
Görüldüğü gibi Spark ortamına verimizi taşıdık. Yapmamız gereken üstüne yazdırmak olacak.
f_tbl <- copy_to(sc, data,
"cardio_spark", overwrite = TRUE)
head(f_tbl)# Source: spark<?> [?? x 13]
age gender height weight ap_hi ap_lo cholesterol gluc smoke alco active
<dbl> <chr> <int> <dbl> <int> <int> <chr> <chr> <chr> <chr> <chr>
1 50 Erkek 168 62 110 80 Normal Norm~ Siga~ Alko~ Aktif
2 55 Kadin 156 85 140 90 Normalin C~ Norm~ Siga~ Alko~ Aktif
3 52 Kadin 165 64 130 70 Normalin C~ Norm~ Siga~ Alko~ Aktif~
4 48 Erkek 169 82 150 100 Normal Norm~ Siga~ Alko~ Aktif
5 48 Kadin 156 56 100 60 Normal Norm~ Siga~ Alko~ Aktif~
6 60 Kadin 151 67 120 80 Normalin U~ Norm~ Siga~ Alko~ Aktif~
# ... with 2 more variables: cardio <chr>, bmi <dbl>
Veriyi başarılı bir şekilde spark ortamına taşıdık ve kopyaladık. Ardından head() komutu ile verinin ilk 6 gözlemini içeren kısmı inceleyebiliriz. Spark ortamına taşıdığımız veri ile çalışabilmek için “dplyr” paketini kullanmamız gerekecek. R içerisindeki tüm fonksiyonlar çalışmayacaktır.
#f_tbl$cholesterol
#str(f_tbl)
#summary(f_tbl)
#nrow(f_tbl)
#apply(f_tbl, 2, mean)R içerisindeki her fonksiyon çalışmıyor. Bu fonksiyonlar çalıştırılınca çıktısı “NULL” olacaktır. Yapılması gereken dplyr paketi ile çalışmaktır.
a<-f_tbl %>% select(height)
head(a)# Source: spark<?> [?? x 1]
height
<int>
1 168
2 156
3 165
4 169
5 156
6 151
Dplyr paketini kullanarak kısa bir kod yazdık. Böylelikle çalıştığı ve analiz yapabilmek için uygun olduğu görülüyor.
select(f_tbl, age, smoke, bmi)# Source: spark<?> [?? x 3]
age smoke bmi
<dbl> <chr> <dbl>
1 50 Sigara icmeyen 22.0
2 55 Sigara icmeyen 34.9
3 52 Sigara icmeyen 23.5
4 48 Sigara icmeyen 28.7
5 48 Sigara icmeyen 23.0
6 60 Sigara icmeyen 29.4
7 61 Sigara icmeyen 37.7
8 62 Sigara icmeyen 30.0
9 48 Sigara icmeyen 28.4
10 54 Sigara icmeyen 25.3
# ... with more rows
Select komutunu kullanarak istediğimiz değişkenleri(sütunları) seçebiliriz.
summarise(f_tbl,
ortalama = mean(bmi),
standart_sapma = sd(bmi),
varyans = var(bmi))# Source: spark<?> [?? x 3]
ortalama standart_sapma varyans
<dbl> <dbl> <dbl>
1 27.6 6.09 37.1
Dplyr paketini kullanarak veri üzerinde özet istatistikler alabiliriz.
f_tbl %>%
group_by(smoke) %>%
summarise(n=n())# Source: spark<?> [?? x 2]
smoke n
<chr> <dbl>
1 Sigara icmeyen 63831
2 Sigara icen 6169
#f <- f_tbl %>%
#group_by(cholesterol) %>%
#summarise(n=n())
#f$nDplyr kullanılarak yeni bir veri kümesi oluşturulmak istenirse, bu durumda “collect” komutu kullanılmalıdır. Aksi takdirde çalıştırılan kodun çıktısı “NULL” olacaktır.
f <- f_tbl %>%
group_by(cholesterol) %>%
summarise(n=n()) %>%
collect()
f$n[1] 8066 52385 9549
Spark ortamına taşınan veriler üzerinde örnek teşkil etmesi adına dplyr paketini kullanarak bazı çalışmalar yapılmıştır. Bununla birlikte SQL sorgusu göndermekte mümkündür.
dbGetQuery(sc, "show databases") namespace
1 default
SQL sorgusu göndererek Spark ortamına taşıdığımız verileri görebiliyoruz.
# db<-dbGetQuery(sc, 'select age, bmi, smoke from cardio_spark where age > 50
# and bmi > 25') head(db)
# dbGetQuery(sc, 'select count(*) as n from cardio_spark where age > 50 and bmi
# > 25')Daha önce dplyr ile yaptılan çalışmalar gibi SQL sorgusu ile veri üzerinde çalışılabilir. Aynı veri setinden “ggplot” paketi kullanarak spark üzerinde grafik oluşturulabilir.
# data2 <- f_tbl %>% filter(bmi>35) %>% select(cardio,active) %>% collect()
# ggplot(data2) + aes(x = cardio, fill = active) + geom_bar(position = 'dodge')
# + scale_fill_brewer(palette = 'Paired') + labs(title =
# 'Aktiflik-Cardio',subtitle ='Çubuk Grafiği') + ggthemes::theme_wsj() +
# theme(legend.position = 'top')4. Büyük Veri Görselleştirme
Veri görselleştirme; verilerin, grafiksel çizelgeler, şekiller ve sütunlar aracılığıyla bilgilerin sunumudur. Doğru zamanda doğru kararları vermemize yardımcı olacak bir dizi içgörü sunar. Stratejik planlamalar yapmak için çok ihtiyaç duyulan bir araçtır. Aslında tam bir karar destek sistemi diyebiliriz. Büyük verilerle uğraştığımızda, veri görselleştirmelerinden aşağıdakiler gibi birçok şekilde yararlanabiliriz:
- Değişkenlerin dağılım özelliklerini anlamak,
- Veri girişi sorunlarını tespit etmek,
- Verilerdeki aykırı değerlerin belirlenmesi,
- Değişkenler arasındaki ilişkileri anlamak,
- Veri analizi için uygun değişkenlerin seçilmesi,
- Tahmine dayalı modellerin sonuçlarını incelemek,
- Sonuçları çeşitli kitlelere iletmek.
Etkili görselleştirmeler geliştirmek, hedeflerin belirlenmesini ve veri analizinin net bir şekilde tasarlanmasını gerektirir. Bazen verilerle ilgili bazı soruların yanıtlarını zaten biliyor olabiliriz; diğer durumlarda, veri analizinin sonraki adımlarına ilişkin daha iyi içgörüler oluşturmak için daha fazla araştırma yapmak ve verileri anlamak isteyebiliriz. Bu süreçte kullanılacak değişken türleri, eksenler, etiketler, lejantlar, renkler vb. birçok unsuru göz önünde bulundurmamız gerekiyor. Ayrıca, görselleştirmeyi belirli bir kitleye sunmayı hedefliyorsak, görselleştirmenin hedef kitle için kullanılabilirliğini ve yorumlanabilirliğini de dikkate almamız gerekir. R’da, bu görselleştirmelerin neredeyse tamamı çok kolay bir şekilde oluşturulabilir.
Etkili bir veri görselleştirmenin geliştirilmesi tipik olarak aşağıdaki adımları içerir:
- Veri görselleştirmenin amacını belirlemek
- Verileri hazırlamak
- Veri görselleştirme hedefine göre ideal görselleştirme aracını belirlemek
- Görselleştirmeyi üretmek
- Görselleştirmedeki bilgileri yorumlamak ve hedef kitleye sunmak
Büyük verileri organize etmemize, değişkenleri yorumlamamıza ve tahmine dayalı modeller için potansiyel değişkenleri belirlememize yardımcı olabilecek R’deki veri görselleştirme araçlarını inceleyeceğiz. 1. bölümde, ggplot2 paketini kullanarak çeşitli veri görselleştirmeleri yapılacaktır. 2. bölümde, plotly kullanarak görselleştirmeler yapılacaktır.
Not: Oluşturulan görsellerde filtreleme, koşullu grafikler ve örneklem kullanma gibi teknikler kullanılmıştır. Bunun sebebi büyük verileri görselleştirme aşamasında, ilgilendiğimiz alan veya kısıtlara göre hareket etme imkanı sağlayan, aynı zamanda daha hızlı avantajını getiren tekniklerdir.
set.seed(101)
data_sample = data[sample(nrow(data), 500), ]4.1 ggplot2
ggplot2 R’daki çok yönlü bir görselleştirme paketidir. Ayrıca, küçük veya büyük veriler için çeşitli görselleştirmeler oluşturmak için basit bir grafik grameri uygular. Bu, minimum miktarda ayarlama ve ince ayar ile kolayca yayınlar ve sunumlar için yüksek kaliteli grafikler oluşturmayı sağlar.
4.1.1 Çubuk Grafiği
Çubuk grafiği, oldukça sık kullanılan grafik türlerinden biridir ve birbirinden farklı kategoriler-gruplar için sayı, frekans vb. bilgileri göstermek ve kıyaslamak için kullanılır. Çubuk grafiklerde yükseklik veya uzunluk, temsil ettikleri verinin değeriyle orantılı olacak şekilde oluşturulur. X ekseni (yatay eksen) farklı kategorileri temsil ettiği için bir ölçeğe sahip değildir. Y ekseni (dikey eksen) bir ölçeğe sahiptir ve ölçüm birimleri bu eksende gösterilir. Çubuklar kategori sayısına, kategori etiketlerinin uzunluğuna veya karmaşıklığına bağlı olarak dikey veya yatay olarak çizilebilir. Çubuk grafiklerin oluşturulabileceği çeşitli yolların olması, bu grafik türünün oldukça esnek olmasını sağlar.
d <- data %>%
dplyr::group_by(cholesterol) %>%
dplyr::summarise(frekans = n()) %>%
dplyr::mutate(kolesterol = cholesterol, Ratio = frekans/sum(frekans), label = percent(Ratio %>%
round(2)))
g <- ggplot(d, aes(x = kolesterol, y = Ratio, label = label, fill = kolesterol)) +
geom_bar(stat = "identity", fill = "indianred3", color = "black") + geom_text(vjust = -0.3)
gggplot(data_sample) + aes(x = cholesterol, fill = cardio) + geom_bar(position = "dodge") +
scale_fill_brewer(palette = "Accent") + labs(title = "Cardio-Aktif olma durumu Cubuk Grafiği") +
ggthemes::theme_hc() + theme(legend.position = "top", axis.text.x = element_text(angle = 55,
vjust = 0.6)) + facet_wrap(vars(active), scales = "free")Çubuk grafiklerine alternatif olarak kullanılabilecek olan nokta grafikleri de mevcuttur. Kullanım alanlarına göre uyarlamak mümkündür. Temel olarak geom_point() fonksiyonu iki sayısal değişkenin aralarındaki ilişikiyi görmek için(korelasyon) kullanılsa da, yapılacak bazı dönüşümler ile farklı şekillerde bize görselleştirme fırsatları sunabilir. Aşağıda bulunan grafikler veride bir filtreleme işlemi kullanılarak ve her defasında grafiğe yeni tanımlamalar yapılarak düzenlenmiştir.
data(gapminder, package = "gapminder")
library(dplyr)
plotdata <- gapminder %>%
filter(continent == "Europe" & year == 2007)ggplot(plotdata, aes(x = lifeExp, y = country)) + geom_point()ggplot(plotdata, aes(x = lifeExp, y = reorder(country, lifeExp))) + geom_point()ggplot(plotdata, aes(x = lifeExp, y = reorder(country, lifeExp))) + geom_point(color = "blue",
size = 2) + geom_segment(aes(x = 40, xend = lifeExp, y = reorder(country, lifeExp),
yend = reorder(country, lifeExp)), color = "lightgrey") + labs(x = "Life Expectancy (years)",
y = "", title = "Life Expectancy by Country", subtitle = "GapMinder data for Europe - 2007") +
theme_minimal() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())4.1.2 Violin Grafiği
Violin (keman) grafiği verilerin dağılımını ve olasılık yoğunluğunu görselleştirmek için en efektif yöntemlerden birisidir. Violin grafiği box plot ve KDE’nin kombinasyonundan doğmuştur. Box plot, görsel basitliği ve verilerdeki değerlerin nasıl dağıldığına ilişkin önemli ayrıntıları gizleme eğiliminde olduğundan, değişken değerlerinin dağılımının gösterilmesinde sınırları bulunmaktadır.
mpg$class = with(mpg, reorder(class, hwy, median))
p <- mpg %>%
ggplot(aes(x = class, y = hwy, fill = class)) + geom_violin() + xlab("class") +
theme(legend.position = "none") + xlab("")
p4.1.3 Histogram ve Yoğunluk Grafiği
Histogram, sayısal verilerin dağılımının grafik bir sunumu ve sürekli değişkenin (niceliksel değişken) olasılık dağılımının bir tahminidir. Bir çeşit çubuk grafik olan bu gösterim şekli Karl Pearson tarafından literatüre kazandırılmıştır (Pearson, 1920). Histogram oluşturmak için öncelikle değer aralığının belirlenmesi gerekir. Bunun için veriler küçükten büyüğe sıralanır. Açıklık değerini bulmak için veri setindeki en büyük sayıdan en küçüğü çıkartılır. Oluşturmak istenen grup sayısı tespit edilir. Daha sonra veri grubunun genişliği bulunur.Genişlik bulunurken açıklık değeri grup sayısına bölünür. Elde edilen genişlik bir üstteki doğal sayı olarak alınır. Histogramlar, verilerin sahip olduğu dağılımın yoğunluğunu gösterir ve değişkenin olasılık yoğunluk fonksiyonunu anlamak için bir tahmin verir. Olasılık yoğunluğu için kullanılan histogramın toplam alanı daima 1’e normalize edilir. X ekseni üzerindeki aralıkların uzunluğu 1 ise, histogram göreceli frekans aralığı ile aynıdır. İlave olarak, yoğunluk tahmini histograma bir alternatif olarak çizilebilir ve genellikle bir kutu kümesi yerine eğri olarak gösterilir (Howitt ve Cramer, 2008). Histogram, incelemesi zaman alacak büyük veri kümelerini grafiksel olarak hızlı biçimde özetler. Histogram kullanımının bir başka faydası, bir üretim işlemi sonuçlarını olması gereken özellik sınırlarıyla karşılaştırır. Histograma süreçleri belirten sınırlar eklenirse, mevcut işlemin “iyi” ürünleri üretip üretemediği hızlı bir şekilde belirlenebilir.
ggplot(data_sample) + aes(x = weight) + geom_histogram(bins = 30L, fill = "darkblue",
position = "identity", color = "orange", alpha = 0.6, ) + ggthemes::theme_fivethirtyeight()g <- ggplot(mpg, aes(cty))
g + geom_density(aes(fill = factor(cyl)), alpha = 0.8) + labs(title = "Density Plot",
subtitle = "Silindir Sayısına Göre Şehir İçi Performans", caption = "Mpg", x = "City Mileage",
fill = "Cylinders")4.1.4 Kutu Grafiği
Kutu grafiği, verilerin dağılımıyla ilgili açıklayıcı bir grafik sunumunu verir. Kutu birinci (Q1) ve üçüncü kuartillerin (Q3) değerlerini, kutunun ortasındaki ağır çizgi medyanı, bıyıklar da çeyreğin değerlerini ve çeyrekler arası aralığın yaklaşık 1,5 katını gösterir. Kutu grafikleri bir değişkene ait verilerin sıklık dağılımını göstermek için kullanılır. Dağılımın şekli, merkezi eğilimi ve değişkenlerin yayılım durumunu tek grafikte göstermesi nedeniyle kullanışlıdır. Kutu grafiği, çeyreklere dayalı grafiksel açıklamadır. Bir kutu grafiğini çizmek için, en küçük değer, alt çeyrek (Q1), ortanca, üst çeyrek (Q3) ve en büyük değerin bulunması gerekir.
Kutu grafiğinde;
- Kutunun uç noktaları Q1 ve Q3’ te yer alır.
- Kutunun uzunluğu Q3-Q1 olarak hesaplanır. Bu fark, aynı zamanda verilerin ortadaki yarısının yayılma ölçüsünü ifade eder.
- Ortanca (median), kutunun içinde çizgi ile gösterilir.
- Kutu dışındaki iki çizgi, alt uç değer ve üst uç değere kadar uzatılır.
mpg %>%
mutate(class = fct_reorder(class, hwy, .fun = "median")) %>%
ggplot(aes(x = reorder(class, hwy), y = hwy, fill = class)) + geom_boxplot() +
xlab("class") + theme(legend.position = "none") + xlab("")4.1.5 Korelasyonlarin İncelenmesi Ve Korelasyon Tablosu
Korelasyon temel anlamda iki değişken arasındaki ilişkiyi göstermek için kullanılır. Olasılık kuramı ve istatistikte iki rassal değişken arasındaki doğrusal ilişkinin yönünü ve gücünü belirtir. Genel istatistiksel kullanımda korelasyon, bağımsızlık durumundan ne kadar uzaklaşıldığını gösterir. Aşağıda verilen korelasyon grafiği bir çok grafik içerisinden seçilmiştir. Mevcut olan korelasyon tablosu ve grafikleri R kütüphanelerinde fazlasıyla çeşitli bulunmaktadır.
corr <- round(cor(mtcars), 1)
ggcorrplot(corr, hc.order = TRUE, type = "lower", lab = TRUE, lab_size = 3, method = "circle",
colors = c("tomato2", "white", "springgreen3"), title = "Correlogram of mtcars",
ggtheme = theme_bw)4.1.6 Saçılım Grafiği
Bilimsel ve mühendislik literatüründe karşılaşılan en yaygın grafiksel gösteri türüdür. Saçılım grafiği, her bir eksende bir değişken olan sayısal veri çiftlerinin (x,y), aralarındaki ilişkiyi gösterir. Saçılım dağılımında, bir x ekseni (yatay eksen) ve bir y ekseni (dikey eksen) ve bir dizi nokta (veriler) bulunur. Dağılım grafiğindeki her nokta, veri kümesindeki bir gözlemi temsil eder. Dağılım çizgisi üzerindeki nokta konumu, x ve y değerlerini temsil eder. Aşağıdaki saçılım grafikleri, gelişmiş bazı özellikler kullanılarak yapılmıştır.
ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) + geom_point()Birimleri Grafige Eklemek
ggplot(mtcars, aes(x = wt, y = mpg, fill = cyl)) + geom_point() + geom_label(label = rownames(mtcars),
nudge_x = 0.25, nudge_y = 0.2) + geom_smooth(method = lm, se = TRUE)Marjinlere Dagilim Eklemek
g <- ggplot(mtcars, aes(x = wt, y = mpg, fill = cyl)) + geom_point() + geom_label(label = rownames(mtcars),
nudge_x = 0.25, nudge_y = 0.2) + geom_smooth(method = lm, se = FALSE)
ggMarginal(g, type = "histogram", fill = "slateblue")ggMarginal(g, type = "density")ggMarginal(g, type = "boxplot")4.2 Plotly
plotly paketi kullanarak daha interaktif görselleştirmeler yapılabilir. Çizgi grafikleri, dağılım grafikleri, alan grafikleri, çubuk grafikler, hata çubukları, kutu grafikleri, histogramlar, ısı haritaları, alt grafikler, çoklu eksenler ve 3B (WebGL tabanlı) grafikler oluşturma fırsatı sunar. Aşağıdaki grafiklerin bir kısmında verinin tamamını kullanarak oluşturulduğunu göreceksiniz. Sonrasında rastgele çekilen örneklem ile oluşturulan grafiğin daha anlaşılır olduğu ortaya çıkacaktır. Ggplot paketinde bahsettiğimiz grafik türlerinin bir kısmını göreceksiniz.
plot_ly(data = data, x = ~bmi, y = ~weight)Tüm veriyi kullanarak oluşturulan saçılım grafiğini yorumlamak ve anlamak zor olabilir. Çalışılan veri büyüdükçe bu durum daha zor hale gelecektir.
plot_ly(data = data_sample, x = ~bmi, y = ~weight)Bu grafikte, bir önceki grafikten farklı olarak çekilen rastgele örneklem kullanılmıştır. Görüldüğü üzere bu yöntem ile grafiğin yorumlanabilirliği ve anlamı artmıştır.
mpg$cyl = as.factor(mpg$cyl)
fig <- mpg
fig <- fig %>%
count(class, cyl)
fig <- fig %>%
plot_ly(x = ~class, y = ~n, color = ~cyl)
figGruplama yöntemiyle oluşturulan bir çubuk grafiğini görüyoruz.
plot_ly(mpg, y = ~hwy, color = ~class, type = "box")Plotly paketi kullanılarak oluşturulan boxplot grafiği ile istatistiksel değerleri görmek mümkündür.
df <- gapminder
fig <- df %>%
plot_ly(x = ~gdpPercap, y = ~lifeExp, size = ~pop, color = ~continent, frame = ~year,
text = ~country, hoverinfo = "text", type = "scatter", mode = "markers")
fig <- fig %>%
layout(xaxis = list(type = "log"))
fig <- fig %>%
animation_opts(1000, easing = "elastic", redraw = FALSE)
fig <- fig %>%
animation_button(x = 1, xanchor = "right", y = 0, yanchor = "bottom")
fig <- fig %>%
animation_slider(currentvalue = list(prefix = "YEAR ", font = list(color = "red")))
figPlotly paketi kullanılarak hareketli görseller oluşturmak mümkündür.
4.3 Paketler İçinde Oluşturulabilecek Animasyonlar
Kullandığımız paketler içerisinde veri görselleştirme aşamasında yapılabilecek en iyi yöntemlerden biri de animasyon oluşturmaktır. Kullandığımız “ggplot2” paketini kullanarak bazı animasyonlar oluşturulmuştur. Farklı verilerden oluşan animasyonları göreceksiniz. Farklı veri tiplerine göre oluşturulabilecek animasyonlar gösterilmek istenmiştir. Plotly ve ggplot gibi paketler içerisinde ulaşabileceğiniz animasyon çeşitleri mevcuttur.
# ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +
# geom_point(alpha = 0.7, show.legend = FALSE) + scale_colour_manual(values =
# country_colors) + scale_size(range = c(2, 12)) + scale_x_log10() +
# facet_wrap(~continent) + labs(title = 'Year: {frame_time}', x = 'GDP per
# capita', y = 'life expectancy') + transition_time(year) + ease_aes('linear')
# anim_save('271-ggplot2-animated-gif-chart-with-gganimate2.gif')# a <- data.frame(group=c('A','B','C'), values=c(3,2,4), frame=rep('a',3)) b <-
# data.frame(group=c('A','B','C'), values=c(5,3,7), frame=rep('b',3)) data <-
# rbind(a,b)
# ggplot(a, aes(x=group, y=values, fill=group)) + geom_bar(stat='identity')
# ggplot(data, aes(x=group, y=values, fill=group)) + geom_bar(stat='identity')
# + theme_bw() +
# transition_states( frame, transition_length = 2, state_length = 1 ) +
# ease_aes('sine-in-out')
# anim_save('288-animated-barplot-transition.gif')# p <- ggplot( gapminder, aes(x = gdpPercap, y=lifeExp, size = pop, colour =
# country) ) + geom_point(show.legend = FALSE, alpha = 0.7) +
# scale_color_viridis_d() + scale_size(range = c(2, 12)) + scale_x_log10() +
# labs(x = 'GDP per capita', y = 'Life expectancy')
# p + transition_time(year) + labs(title = 'Year: {frame_time}') +
# shadow_wake(wake_length = 0.1, alpha = FALSE)# mean.temp <- airquality %>% group_by(Month) %>% summarise(Temp = mean(Temp))
# mean.temp
# a <- ggplot(mean.temp, aes(Month, Temp, fill = Temp)) + geom_col() +
# scale_fill_distiller(palette = 'Reds', direction = 1) + theme_minimal() +
# theme( panel.grid = element_blank(), panel.grid.major.y = element_line(color
# = 'white'), panel.ontop = TRUE )
# a + transition_states(Month, wrap = FALSE) + shadow_mark()5. Büyük Veri Modelleme
5.1 Makine Öğrenmesi Nedir?
Matematiksel ve istatistiksel işlemler ile veriler üzerinden çıkarımlar yaparak tahminlerde bulunan sistemlerin bilgisayarlar ile modellenmesidir. Yapay zekanın, bir alt birim dalıdır. Veriler tam anlamıyla belge, ses, görüntü vb. gibi bilgiler anlamına gelir. Model ise makine öğreniminin son ürünüdür. Peki makine öğrenmesi süreci nelerden oluşuyor? Makine Öğrenimi, analitik modellerin yetersiz kaldığı durumlarda sorunları çözmek için oluşturulmuştur. Denklemler ve yasalar ümit vaat etmediğinde eğitim verilerini kullanarak bir model elde etmek için Makine Öğrenimi tekniklerinden yararlanırız.
5.2 Makine Öğrenmesi Nasıl Çalışır?
Makine öğrenimi algoritmaları, insan müdahalesi olmadan verilerden öğrenebilen ve deneyimler ile geliştirebilen programlardır. Makine öğrenimi algoritmaları denetimli öğrenme ve denetimsiz öğrenme olarak kategorize edilir.
5.2.1 Denetimli Öğrenme
Denetimli makine öğrenimi , belirsizlik dahilinde kanıta dayalı tahminler yapan bir model oluşturur. Denetimli bir öğrenme algoritması bilinen bir girdi verisi seti ve verilere bilinen yanıtları alır, ardından yeni verilere yanıt için makul tahminler oluşturmak üzere bir modeli eğitir. Tahmin etmeye çalıştığınız çıktı için bilinen verileriniz varsa denetimli öğrenmeyi kullanabilirsiniz.
Sınıflandırma Teknikleri
Örneğin bir e-postanın gerçek mi yoksa spam mı yoksa bir tümörün kanserli mi yoksa iyi huylu mu olduğu gibi, farklı yanıtlar öngörür. Sınıflandırma modelleri girdi verilerini kategorilere ayırır.
Verileriniz etiketlenebilir, kategorilere ayrılabilir veya belirli gruplara sınıflara ayrılabiliyorsa sınıflandır tekniğini kullanabilirsiniz. Örneğin, el yazısı tanıma uygulamaları harfleri ve sayıları tanımak için sınıflandırmayı kullanır. Sınıflandırma yapmak için yaygın algoritmalar, destek vektör makinesi(SVM) , karar ağaçları , k-en yakın komşu , Naive Bayes , diskriminant analizi, lojistik regresyon ve sinir ağlarını içerir.
Regresyon Teknikleri
Sürekli bir değeri tahmin etmek için kullanılır. Evin büyüklüğü, fiyatı vb. özellikleri göz önüne alındığında bir evin fiyatlarının tahmin edilmesi, regresyonun yaygın örneklerinden biridir. Bir veri aralığıyla çalışıyorsanız veya yanıtınızın niteliği sıcaklık veya bir ekipman parçasının arızalanmasına kadar geçen süre gibi gerçek bir sayı ise regresyon tekniklerini kullanabilrsiniz. Yaygın regresyon algoritmaları arasında doğrusal model , doğrusal olmayan model, regülasyon, kademeli regresyon , karar ağaçları , sinir ağları sayılabilir.
5.2.2 Denetimsiz Öğrenme
Denetimsiz (gözetimsiz) öğrenme, modeli denetlemenize gerek olmayan bir makine öğrenme tekniğidir. Bunun yerine, modelin bilgileri keşfetmek için kendi başına çalışmasına izin vermeniz gerekir. Denetimsiz öğrenme algoritmaları, denetimli öğrenmeye kıyasla daha karmaşık işleme görevleri gerçekleştirmenizi sağlar. Denetimsiz öğrenmede sistem öğretilmiyor, verilerden öğreniyor. Denetimsiz makine öğrenimi, verilerdeki bilinmeyen her türlü paterni bulur. Denetimsiz yöntemler, kategorizasyon için yararlı olabilecek özellikleri bulmanıza yardımcı olur.
6. Denetimli Makine Öğrenmesi
6.1 Train ve Test
Şekil 6.1: Train ve Test
Kullanacağımız modellerin tahmin performansını ölçmek için veriyi train ve test olarak ikiye bölmemiz gerekiyor. Bölüm 2.3’de belirttiğimiz yöntemlerden ilki (örneklem çekme) kullanıldı. Bu kadar büyük bir verinin hepsini modellere sokmaya çalışırsak hem sağlıklı sonuçlar alamayacağız, hem de kodların çalışması için çok uzun süre beklememiz gerekecek. Bu sebeple 500 gözlem içeren bir rastgele örneklem kullanıldı.
set.seed(101)
sample = sample.int(n = nrow(data_sample), size = floor(0.75 * nrow(data_sample)),
replace = F)
train_sample = data_sample[sample, ]
test_sample = data_sample[-sample, ]Çektiğimiz örneklemi %75’i train, %25’i test olacak şekilde rastgele ayırdık.
6.2 Destek Vektör Makineleri
Şekil 6.2: DVM
Destek Vektör Makineleri, temel olarak iki sınıfa ait verileri birbirinden en uygun şekilde ayırmak için kullanılır. Bunun için karar sınırları ya da diğer bir ifadeyle hiper düzlemler belirlenir. DVM’ler günümüzde yüz tanıma sistemlerinden, ses analizine kadar birçok sınıflandırma probleminde kullanılmaktadırlar.
Avantajları:
- Yüksek boyutlu uzaylarda etkilidirler.
- Boyut sayısının, örnemlem sayısından fazla olduğu durumlarda etkilidirler.
- Karar fonksiyonunda bir takım eğitim noktaları kullanılır (“destek vektörler”). Dolayısıyla bellek verimli bir şekilde kullanılmış olur.
- Çok yönlü: Karar fonksiyonu için çok farklı çekirdek fonksiyonları (“kernel functions”) kullanılabilmektedir.
R üzerinde nasıl çalıştığını görelim:
classifier1 = svm(formula = cardio ~ ., data = train_sample, scale = FALSE, type = "C-classification",
kernel = "linear")Train setimizle modeli kurduk.
summary(classifier1)
Call:
svm(formula = cardio ~ ., data = train_sample, type = "C-classification",
kernel = "linear", scale = FALSE)
Parameters:
SVM-Type: C-classification
SVM-Kernel: linear
cost: 1
Number of Support Vectors: 256
( 127 129 )
Number of Classes: 2
Levels:
Var Yok
Modeli özetlediğimizde kullanılan destek vektör sayısı ve bağımlı değişkeni görebiliyoruz.
y_pred = predict(classifier1, newdata = test_sample[-12])
cmlinear = table(test_sample[, 12], y_pred)
cmlinear y_pred
Var Yok
Var 39 25
Yok 15 46
Train seti üzerinde kurduğumuz modelin, test seti üzerindeki tahminlerini görüyoruz.
accuracylinear = sum(diag(cmlinear))/dim(test_sample)[1]
accuracylinear[1] 0.68
Son olarak bu tahminlerin doğruluk oranını hesapladık. %68 oranında bir doğruluk yakaladık.
6.3 Karar Ağaçları
Çok güçlü algoritmalar olan karar ağaçları kompleks ve büyük veri setlerinin çözümünde oldukça yararlanılan denetimli öğrenme algoritmaları ailesine aittir. Bunun yanında karar ağaçları rastgele orman (random forests) algoritmalarının temel bileşenleridir.
Şekil 6.3: Karar Ağaçları
Karar ağaçları ilk olarak recursive binary splitting ile başlar. Böylelikle regresyon için hata kareler ortalamasını, sınıflandırma için ise classification error rate, gini index veya deviance gibi prediction perfrormansına dayalı ölçekleri minimum yapacak en büyük ağaç (bushy tree) belirlenir. Regresyon modelinin yanıtı her gözlemin ait olduğu sınıfın ortalamsıdır. Bu yöntemin bir dezavantajı overfitting’dir. Yöntem training seti çok iyi öğrenir ancak test seti üzetindeki performansı düşüktür.
Karar ağaçlarında hedef değişken kategorik ise sınıflandırma algoritması, numerik değişken ise regresyon algoritması kullanılır. Veri setindeki hedef değişkenimiz kategorik olduğu için sınıflandırma algoritması kullanılacaktır.
Karar Ağaçlarının Avantajları:
- Anlaması ve yorumlaması kolaydır. Kullanılan ağaç yapılar görselleştirilebilir.
- Az oranda bir veri hazırlığına ihtiyaç duyar. Fakat unutulmamalıdır ki bu model kayıp değerleri desteklememektedir.
- Kullanılan ağacın maliyeti, ağacı eğitmek için kullanılan veri noktalarının sayısıyla logaritmiktir.
- Hem sayısal hem de kategorik verileri işleyebilir.
- Çok çıktılı problemleri ele alabilmektedirler.
- İstatistiksel testler kullanılarak bir modelin doğrulanması mümkündür.
- Karar ağaçları, parametrik olmayan bir yöntem olarak düşünülebilir. Yani uzay dağılımı ve sınıflandırma yapısı hakkında bir yaklaşıma sahip değilledir.
R üzerinde nasıl çalıştığını görelim:
set.seed(101)
tree.model1 = tree(cardio ~ ., data = train_sample)
summary(tree.model1)
Classification tree:
tree(formula = cardio ~ ., data = train_sample)
Variables actually used in tree construction:
[1] "ap_hi" "weight" "ap_lo" "height" "active" "gluc"
Number of terminal nodes: 10
Residual mean deviance: 1.014 = 369.9 / 365
Misclassification error rate: 0.2347 = 88 / 375
Train seti ile modelimizi kurduk. Özet çıktısında ortalama sapma ve hata oranı gibi değerleri görebiliyoruz.
plot(tree.model1)
text(tree.model1, pretty = 0)Grafiğini çizdirdiğimizde ise ağacın nasıl bir şekil aldığını görebiliyoruz.
Bu sefer train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.
%62.4 doğruluk oranına sahibiz.
6.3.1 Budama
Budamada da aynı lasso regresyonda olduğu gibi bir penalization terimi mevcuttur. Amaç fonksiyonumuza \(\alpha|T|\) şeklinde bir kısıt vardır. Burada \(\alpha\) cost complexcity parametresi, \(|T|\) toplam node sayısını göstermektedir. Lasso’da olduğu gibi \(\alpha\) büyüdükçe modelde kullanılan node sayısı düşecek ancak modelin yanlılığıda artacaktır. Budamada optimal \(\alpha\) değerinin belirlenmesi için çapraz doğrulama (cross validation) kullanılır.
Şekil 6.3.1: Budama
set.seed(101)
tree.model2 = cv.tree(tree.model1, FUN = prune.misclass)
tree.model2$size
[1] 10 9 8 6 5 2 1
$dev
[1] 111 111 121 113 112 112 182
$k
[1] -Inf 0.000000 1.000000 2.000000 3.000000 3.666667 74.000000
$method
[1] "misclass"
attr(,"class")
[1] "prune" "tree.sequence"
plot(tree.model2)Optimal \(\alpha\) değerinin belirlenmesi için çizdirdiğimiz bu grafikte en yakın ve en düşük değeri almamız gerekiyor. Görüldüğü üzere, misclassification’ın en düşük değeri, size=2 olduğunda elde edilmiştir.
set.seed(12345)
tree.model2 = prune.misclass(tree.model1, best = 2)Size=2 kullanarak modeli tekrar kurduk. Oluşan ağaca bakalım.
fit <- rpart(cardio ~ ., data = train_sample, method = "class")
rpart.plot(fit, extra = 106)İlk grafik gibi karışık olmayan bir ağaç yapısıyla karşılaştık. Özet çıktılarını da alalım.
summary(tree.model2)
Classification tree:
snip.tree(tree = tree.model1, nodes = 3:2)
Variables actually used in tree construction:
[1] "ap_hi"
Number of terminal nodes: 2
Residual mean deviance: 1.2 = 447.6 / 373
Misclassification error rate: 0.2853 = 107 / 375
Tahmin performansına bakıp bitirelim.
Görüldüğü gibi modelin test seti üzerindeki accuracy’si (doğruluk oranı) %66.4’dür. Doğru sınıflandırma yüzdesi artmıştır ve yorumlanması daha kolay bir ağacımız olmuştur.
6.4 Torbalama (Bagging)
Karar Ağaçları yüksek varyansa sahiptir. Bu problemi çözmek için Torbalama kullanılabilir. Torbalama iki temele dayanan son derece güçlü bir fikirdir:
- Ortalama Alma: Varyansı azaltır.
- Önyükleme (Bootstrapping): Bol miktarda eğitim veri seti.
bknz. Bagging (Torbalama) / Bootstrap Aggregating (Önyükleme Toplaması)
Şekil 6.4: Torbalama
Orjinal veri setinden elde edilen önyükleme örneklerine tahminciler uygulanarak bir topluluk oluşturulur. Burada önyükleme uygulaması, iadeli rastgele seçim yapıp alt örneklemler oluşturmak için kullanılır.
Oluşturulan alt örneklemler orjinal veri setindeki sayı ile aynı olacaktır. Bu nedenle bazı gözlemler önyükleme sonucunda oluşturulan örneklemlerde yer almazken bazıları iki veya daha fazla defa görülebilir. Tahminlerin birleştirilmesi aşamasında regresyon ağaçları için ortalama alınırken sınıflandırma ağaçlarında sonuçlar oylama ile belirlenir.
Torbalama, tutarsız bir tahminci değişkenin tahmin geçerliliğini de arttırabilir. Düşük yanlılık miktarına sahip ama yüksek varyanslı olan değişkenleri kullanarak onları daha elverişli hale getirir. Ayrıca deneysel sonuçlara göre torbalama yöntemi, tekil ağaçlara göre daha etkin sonuçlar vermektedir.
- Orjinal veri kümesinden çoklu alt kümeler oluşturulur.
- Bu alt grupların her birinde bir temel model (zayıf model) oluşturulmuştur.
- Modeller paralel olarak çalışır ve birbirinden bağımsızdır.
- Nihai tahminler, tüm modellerden gelen tahminler birleştirilerek belirlenir.
Modeli kuralım:
set.seed(101)
Bagging.model1 = randomForest(cardio ~ ., data = train_sample, mtry = 12, importance = TRUE)
Bagging.model1
Call:
randomForest(formula = cardio ~ ., data = train_sample, mtry = 12, importance = TRUE)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 12
OOB estimate of error rate: 33.87%
Confusion matrix:
Var Yok class.error
Var 119 62 0.3425414
Yok 65 129 0.3350515
- mtray: Değişken Sayısı (p)
- Varsayılan örneklem sayısı 500.
Bagging modelimizi kurduk. Konfüzyon matris ve hata oranlarını görebiliyoruz.
varImpPlot(Bagging.model1, main = "Bagging Model")Değişkenlerin doğruluk ve gini ölçütlerine göre önemlilik derecelerini bu grafik ile görebiliyoruz.
Büyük tansiyon (ap_hi) 2 grafikte de en önemli değişken olarak gözüküyor.
Modelin tahmin performansını inceleyelim.
Tekrardan train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz. %66.4 doğruluk oranına sahibiz.
Varsayılan olarak 500 örneklem kullanmıştık. Hata grafiğine bakıp bunu daha aza indirebilecek miyiz bakalım.
plot(Bagging.model1, main = "Bagging Model")Eğer belli bir ağaç sayısından sonra çizgiler düzleşmeye başlasaydı o kısmı sınır olarak alıp iş yükümüzü hafifletebilirdik. Ancak bu grafiğe baktığımızda böyle bir şansımız olmadığını görüyoruz.
6.5 Rastgele Orman (Random Forest)
Çok etkili bir istatistiksel öğrenme yöntemidir. Bagging fikri üzerine kuruludur, ancak iyileştirme sağlar çünkü ağaçları korelasyonsuzlaştırır. Yine aynı şekilde bootstrap eğitim setleri üzerinde karar ağaçları inşaa edeceğiz fakat bu sefer farklı olarak, her bir ayrışımı yaparken p tane açıklayıcı değişkenin herbirini hesaba katmak yerine, bunlar içinden rasgele seçilen m tanesini kullanacağız. Böylelikle herbir bootstrap eğtim seti üzerinde çok çeşitli ağaçlar elde edilecek. Burada devreye ek bir parametre olarak seçilecek değişken sayısı girecek. Seçilecek değişken sayısı genel olarak \(\sqrt p\) şeklinde belirlenir. m=p durumunda ise random forest bagging’e dönüşür.
Şekil 6.5: Rastgele Orman
Neden bölünme için tüm p açıklayıcı değişken yerine rastgele bir m tanesini düşünüyoruz?
- Varsayalım ki, diğer bazı orta derecede güçlü açıklayıcı değişkenler ile birlikte veri setinde çok güçlü bir açıklayıcı değişken var. O zaman bagging ağaçlarının çoğu veya hepsi ilk bölünme için çok güçlü açıklayıcı değişkeni kullanacak.
- Bütün bagging ağaçları benzer görünecektir. Bu nedenle yapılan tüm tahminler yüksek oranda ilişkili olacaktır.
- Yüksek korelasyonlu niceliklerin ortalamasının alınması varyansı pek fazla düşürmez. Random forests bagging ağaçlarını korelasyonsuzlaştırarak varyanstaki düşüşü arttırır.
Şimdi mtray değerini \(\sqrt p\) alarak randomforest yapalım.
set.seed(101)
Randomforest.model1 = randomForest(cardio ~ ., data = train_sample, mtry = 4, importance = TRUE)
Randomforest.model1
Call:
randomForest(formula = cardio ~ ., data = train_sample, mtry = 4, importance = TRUE)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 4
OOB estimate of error rate: 32.27%
Confusion matrix:
Var Yok class.error
Var 122 59 0.3259669
Yok 62 132 0.3195876
Rastgele orman modelimizi kurduk. Konfüzyon matris ve hata oranlarını görebiliyoruz.
varImpPlot(Randomforest.model1, main = "Random Forest Model")Tekrardan değişkenlerin önemlilik derecelerine bakıyoruz. ap_hi (büyük tansiyon) değişkeni yeniden en önemli değişken olarak gözüksede gini grafiğinde bmi (vücut kitle indeksi) en önemlisi olarak gözüküyor.
Modelin performansını inceleyelim.
Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.
%66.4 doğruluk oranına sahibiz. Bagging ile aynı sonucu aldık.
6.6 Yükseltme (Boosting)
Boosting’de bagging ve random forest gibi tahmin performansını arttırmaya yönelik bir yaklaşımdır. Onlardan farklı olarak boosting iterative bir yaklaşımdır ve her adımında bir önceki adımdaki performansı geliştirmeye çalışır.
Bagging ve random forest’ta her bir bootstrap training seti üzerine kurulabilecek en büyük ağaçlar kurulur ve böylece tahminlerin yanlılığı düşürülür. Ortalama alınarak tahminlerin varyansı indirgenmiş olunur. Boosting’de ise her adımda nispeten daha küçük bir ağaç kurulur ve o ağaçtan elde edilen bilgi bir sonraki adıma aktarılır. Böylece öğrenme yavaş yavaş gerçekleşir ve overfitting oluşmaz.
Şekil 6.6: Yükseltme
Yükseltme yöntemindeki temel fikir, veri setine farklı ağırlıklar verilmesi sonucu elde edilen ağaçlar topluluğundan çıkarsamalar yapılmasıdır. Başlangıçta tüm gözlemler eşit ağırlığa sahiptir. Ağaç topluluğu büyümeye başladıkça, problem bilgisine kurulu olarak ağırlıklandırmalar düzenlenir. Yanlış sınıflandırılan gözlemlerin ağırlığı arttırılırken, nadiren yanlış sınıflandırılan gözlemlerin ağırlığı azaltılır. Bu sayede ağaçlar zor durumlar karşısında kendini düzenleyebilme yeteneği kazanır.
Yükseltme yönteminin nasıl çalıştığını aşağıdaki adımlarla anlayalım:
- Orjinal veri kümesinden bir alt küme oluşturulur.
- Başlangıçta, tüm veri noktalarına eşit ağırlık verilir.
- Bu alt kümede bir temel model oluşturulur.
- Bu model, tüm veri kümesi için tahminler yapmak için kullanılır.
- Hatalar gerçek değerler ve öngörülen değerler kullanılarak hesaplanır.
- Yanlış öngörülen gözlemlere daha fazla ağırlık verilir. (Burada, sınıflandırılmamış olan üç tane mavi artı noktaya daha fazla ağırlık verilecektir.)
- Başka bir model oluşturulur ve veri setinde tahminler yapılır. (Bu model önceki modeldeki hataları düzeltmeye çalışır.)
- Benzer şekilde, her biri önceki modelin hatalarını düzelten çoklu modeller oluşturulur.
- Son model (güçlü öğrenen), tüm modellerin ağırlıklı ortalamasıdır.
Boosting modelini oluşturalım:
train_sample$cardio = ifelse(train_sample$cardio == "Var", 1, 0)
train_sample$cardio = factor(train_sample$cardio)
test_sample$cardio = ifelse(test_sample$cardio == "Var", 1, 0)
test_sample$cardio = factor(test_sample$cardio)Öncelikle bağımlı değişkenimizin (cardio) Var çıktısı 1, Yok çıktısını 0 olarak tekrardan atadık. Boosting modelin kurulması için gerekli.
set.seed(101)
boosting.model1 = gbm((unclass(cardio) - 1) ~ ., data = train_sample, distribution = "bernoulli",
n.trees = 5000, interaction.depth = 3, verbose = F)
summary(boosting.model1) var rel.inf
bmi bmi 26.3231924
weight weight 16.0032169
age age 14.5861669
height height 14.1836009
ap_hi ap_hi 10.3048401
ap_lo ap_lo 6.7740393
cholesterol cholesterol 3.4637669
gluc gluc 2.3314691
gender gender 2.1389382
smoke smoke 1.7647568
active active 1.4590009
alco alco 0.6670116
Modeli kurup özetini aldığımızda bagging ve random forest’ta gördüğümüz tarzda değişken önemliliğini gösteren bir grafikle karşılaşıyoruz.
Görüldüğü üzere bmi (vücut kitle indeksi) değişkeni en etkili değişken olarak gözüküyor.
Modelin performansına bakalım:
Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.
%64.8 doğruluk oranına sahibiz.
6.7 Lojistik Regresyon
Lojistik regresyon analizi, sınıflama ve atama işlemi yapmaya yardımcı olan bir regresyon yöntemidir. Bağımlı değişken üzerinde açıklayıcı değişkenlerin etkileri olasılık olarak elde edilerek risk faktörlerinin olasılık olarak belirlenmesi sağlanır. Lojistik regresyonun amacı, iki yönlü karakteristiği olan bağımlı değişkenle ilgili bir dizi bağımsız değişken arasında uygun ilişkiyi tanımlamak için en uygun modeli bulmaktır.
Lineer regresyonda bağımsız değişkenlerin parametreleri Ordinary Least Squares (OLS) yöntemiyle tahmin edilirken Lojistik regresyonda parametreler Maximum Likelihood (MLE) yöntemiyle hesaplanıyor. MLE yönteminin amacı sonsuz parametre havuzundan veri setinin görülme olasılığını maksimize eden en iyi parametreleri seçmek.
Şekil 6.7: Lojistik Regresyon
Lojistik regresyon, bir sonucu belirleyen bir veya daha fazla bağımsız değişken bulunan bir veri kümesini analiz etmek için kullanılan istatistiksel bir yöntemdir. Sonuç, ikili bir değişkenle ölçülür (yalnızca iki olası sonuç vardır).
Lojistik regresyonda, bağımlı değişken ikili veya ikili, yani yalnızca 1 (doğru, başarı, hamile vb.) Veya 0 (yanlış, hata, gebe olmayan vb.) Olarak kodlanmış verileri içeriyor.
Lojistik regresyonun amacı, iki yönlü karakteristiği (bağımlı değişken = yanıt veya sonuç değişkeni) ile ilgili bir dizi bağımsız (öngörücü veya açıklayıcı) değişken arasındaki ilişkiyi tanımlamak için en uygun (henüz biyolojik olarak makul) modeli bulmaktır.
Lojistik regresyon modelini kuralım:
lojistik.model <- glm(cardio ~ ., data = train_sample, family = binomial)
summary(lojistik.model)
Call:
glm(formula = cardio ~ ., family = binomial, data = train_sample)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.4084 -0.9295 -0.4810 0.9462 2.0428
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.105e+01 5.668e+00 -1.950 0.0512 .
age 2.432e-02 1.835e-02 1.325 0.1851
genderKadin -2.233e-01 3.071e-01 -0.727 0.4672
height 2.819e-03 3.314e-02 0.085 0.9322
weight 2.518e-02 2.774e-02 0.908 0.3639
ap_hi 5.428e-02 9.033e-03 6.009 1.87e-09 ***
ap_lo -1.218e-04 1.226e-03 -0.099 0.9209
cholesterolNormalin Cok Ustunde 8.470e-01 3.981e-01 2.128 0.0334 *
cholesterolNormalin Ustunde -6.869e-02 3.385e-01 -0.203 0.8392
glucNormalin Cok Ustunde -9.835e-01 4.823e-01 -2.039 0.0414 *
glucNormalin Ustunde -4.879e-01 4.749e-01 -1.027 0.3042
smokeSigara icmeyen 4.717e-01 4.306e-01 1.095 0.2733
alcoAlkol icmeyen 9.246e-01 5.691e-01 1.625 0.1042
activeAktif Degil 5.308e-01 3.000e-01 1.769 0.0769 .
bmi -2.573e-02 6.570e-02 -0.392 0.6953
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 519.41 on 374 degrees of freedom
Residual deviance: 428.31 on 360 degrees of freedom
AIC: 458.31
Number of Fisher Scoring iterations: 5
Regresyon modelimizi kurduk. Hata, z değerleri, AIC vb. çoğu değeri görebiliyoruz. Tahmin performansına bakalım.
Train seti ile kurduğumuz modelin test seti üzerindeki tahminlerini ve duyarlılık, özgüllük, doğruluk değerlerini konfüzyon matris ile görüyoruz.
%68 doğruluk oranına sahibiz.
6.7.1 Çoklu Bağlantı (Multicollinearity)
Regresyonda, “çoklu bağlantı”, diğer tahmin edicilerle ilişkili tahmin edicileri ifade eder. Çoklu bağlantı, modeliniz yalnızca yanıt değişkeninizle değil, aynı zamanda birbirleriyle de ilişkili olan birden çok faktör içerdiğinde ortaya çıkar. Başka bir deyişle, biraz fazla olan faktörleriniz olduğunda ortaya çıkar.
Eğer modelimizde çoklu bağlantı problemi var ise bunu düzeltip tekrar bakmamız gerekiyor. Bu problemin varlığını kontrol etmek için en kolay yöntem vif kodunu kullanmaktır.
vif(lojistik.model) GVIF Df GVIF^(1/(2*Df))
age 1.071497 1 1.035132
gender 1.613481 1 1.270229
height 5.240991 1 2.289321
weight 9.557930 1 3.091590
ap_hi 1.204384 1 1.097444
ap_lo 1.098764 1 1.048220
cholesterol 1.237484 2 1.054715
gluc 1.305899 2 1.068999
smoke 1.380185 1 1.174813
alco 1.214596 1 1.102087
active 1.039142 1 1.019383
bmi 9.109234 1 3.018151
Vif değeri 10’dan büyük değerler olduğu zaman çoklu bağlantı probleminden söz edebiliyoruz. Baktığımızda 10’dan büyük bir değerle karşılaşmıyoruz. Çoklu bağlantı problemimiz yok.
6.8 En İyi Model
| MODEL | DOĞRULUK ORANI |
|---|---|
| Destek Vektör Makineleri | %68 |
| Karar Ağaçları | %62.4 |
| Budama (Pruning) | %66.4 |
| Torbalama (Bagging) | %66.4 |
| Rastgele Orman | %66.4 |
| Yükseltme (Boosting) | %64.8 |
| Lojistik Regresyon | %68 |
Tablodan her yöntem için accuracy (doğruluk) oranı değerlerine baktığımızda DVM ve Lojistik Regresyon yöntemlerinin bu veri için en iyi çalışan yöntemler olduğunu söyleyebiliriz.
7. Denetimsiz Makine Öğrenmesi
Denetimsiz makine öğrenme tekniklerinin bazı uygulamaları şunlardır:
Kümeleme, veri kümesini benzerliklerine göre otomatik olarak gruplara ayırır.
Anomali tespiti, veri kümenizdeki olağandışı veri noktalarını keşfedebilir. Hileli işlemler bulmak için yararlıdır.
İlişkilendirme madenciliği, veri kümenizde genellikle birlikte ortaya çıkan öğe kümelerini tanımlar.
Gizli değişken modeller, veri ön işleme için yaygın olarak kullanılmaktadır. Veri kümesindeki özellik sayısını azaltmak veya veri kümesini birden çok bileşene ayırmak gibi problemlerde kullanılabilir.
Denetimli ve denetimsiz makine öğrenimi arasında seçim yapma konusunda karar vermek istiyorsanız:
Bir tahmin yapmak için bir (örneğin, sıcaklık veya hisse senedi fiyatı veya bir sınıflandırma gibi sürekli bir değişkenin gelecekteki değeri), örneğin, web kamerası video çekimlerindeki araba markalarını tanımlamak için bir model eğitmeniz gerekiyorsa denetimli öğrenmeyi seçin.
Verilerinizi keşfetmeniz gerekiyorsa ve verileri kümelere ayırmak gibi iyi bir dahili temsil bulmak için bir model eğitmek istiyorsanız, denetimsiz öğrenmeyi seçin.
7.1 Kümeleme Nedir?
Şekil 7.1: Kümeleme
Denetimsiz öğrenme söz konusu olduğunda kümelenme önemli bir kavramdır. Genel olarak, kategorize edilmemiş verilerden oluşan bir koleksiyonda bir yapı veya model bulma ile ilgilenir. Kümeleme algoritmaları verilerinizi işler ve verilerde varsa doğal kümeleri (grupları) bulur. Ayrıca algoritmalarınızın kaç kümeyi tanımlaması gerektiğini de değiştirebilirsiniz. Bu grupların ayrıntı düzeyini ayarlamanıza olanak tanır.
7.2 K-Means Kümeleme
K, her yineleme için en yüksek değeri bulmanıza yardımcı olan yinelemeli bir kümeleme algoritması anlamına gelir. Başlangıçta, istenilen sayıda küme seçilir. Bu kümeleme yönteminde, veri noktalarını k gruplarına kümelemeniz gerekir. Daha büyük bir k, aynı şekilde daha fazla ayrıntıya sahip daha küçük gruplar anlamına gelir.
Şekil 7.2: K-Means Kümeleme
Şimdi R üzerinde bu analizin nasıl yapıldığını göreceğiz. Ancak analize geçmeden önce daha önceden büyük verimizden çektiğimiz 500 gözlemlik örneklemi daha da küçültüp (50 gözleme indirip) sağlıklı bir görsel oluşturacağız.
set.seed(103)
data_sample2 = data_sample[sample(nrow(data_sample), 50), ]
df = data_sample2 %>%
select(age, height, weight, ap_hi, ap_lo, bmi) %>%
scale()
head(df) age height weight ap_hi ap_lo bmi
69081 -0.5352747 0.6332190 -1.69631233 -1.2231343 -1.0253132 -1.8907022
48683 -0.3994182 -0.1517632 0.05762952 1.4709941 0.7273589 0.1236830
24104 -1.2145573 -0.6750848 -0.75670063 -0.3250915 -0.1489771 -0.5117913
51237 -1.7579834 1.1565406 2.25005683 -0.3250915 -0.1489771 1.5877724
6743 0.6874340 -1.3292367 -0.06765204 -0.7741129 -0.1489771 0.5569583
1329 0.6874340 1.1565406 1.99949371 4.1651224 3.3563671 1.3587831
50 gözlem içeren yeni bir örneklem oluşturduk. Select komutu ile sadece nümerik değişkenleri (k-means kümeleme yöntemi nümerik değişkenlerle çalıştığı için) seçtik. Scale komutu ile de ölçeklendirme yaptık. Şimdi kümelemeye hazırız.
k2 = kmeans(df, centers = 2, nstart = 25)
str(k2)List of 9
$ cluster : Named int [1:50] 1 2 1 2 1 2 1 1 1 2 ...
..- attr(*, "names")= chr [1:50] "69081" "48683" "24104" "51237" ...
$ centers : num [1:2, 1:6] -0.173 0.445 -0.13 0.334 -0.466 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:2] "1" "2"
.. ..$ : chr [1:6] "age" "height" "weight" "ap_hi" ...
$ totss : num 294
$ withinss : num [1:2] 109.8 93.1
$ tot.withinss: num 203
$ betweenss : num 91.1
$ size : int [1:2] 36 14
$ iter : int 1
$ ifault : int 0
- attr(*, "class")= chr "kmeans"
nstart: Çoklu başlangıç noktası atamak için kullanılıyor.
centers: k tane merkez noktası oluşturmak için kullanılıyor.
Öncelikle kendi belirdiğimiz k ile analizimizi yaptık. Rastgele olarak k=2 seçtim ve veriyi ikiye ayırmış olduk. Hangi gözlemin hangi kümede olduğu, kümelerin gözlem sayısı gibi özellikleri görebiliyoruz.
fviz_cluster(k2, data = df)Burada ise grafik üzerinde kümelemenin nasıl yapıldığını görüyoruz. Şimdi eğer k değerini farklı verseydik ne olacağını görelim.
k3 <- kmeans(df, centers = 3, nstart = 25)
k4 <- kmeans(df, centers = 4, nstart = 25)
k5 <- kmeans(df, centers = 5, nstart = 25)
p1 <- fviz_cluster(k2, geom = "point", data = df) + ggtitle("k=2")
p2 <- fviz_cluster(k3, geom = "point", data = df) + ggtitle("k=3")
p3 <- fviz_cluster(k4, geom = "point", data = df) + ggtitle("k=4")
p4 <- fviz_cluster(k5, geom = "point", data = df) + ggtitle("k=5")
grid.arrange(p1, p2, p3, p4, nrow = 2)k=2,3,4 ve 5 değerleri için kümelerin nasıl ayrıldığını görüyoruz. En iyi k değerlerini bulmak için kullanılan bazı yöntemler var. Şimdi onlara bakalım.
7.2.1 Elbow Yöntemi
- Kümeler için hata hesaplama.
set.seed(134)
fviz_nbclust(df, kmeans, method = "wss")Genel olarak en büyük düşüşün yaşandığı k seçilir. Burada 2 ve 3 değerleri uygun gibi duruyor. Sonraki yöntemimize bakıp karar verelim.
7.2.2 Average Silhoutte Yöntemi
- Küme içi kalite skoru hesaplama.
fviz_nbclust(df, kmeans, method = "silhouette")Burada da görüldüğün üzere k=2 seçmek en mantıklı seçim olacaktır.
set.seed(123)
final <- kmeans(df, 2, nstart = 24)
print(final)K-means clustering with 2 clusters of sizes 14, 36
Cluster means:
age height weight ap_hi ap_lo bmi
1 0.4448331 0.3341782 1.198587 0.9642413 0.9151452 1.0817642
2 -0.1729906 -0.1299582 -0.466117 -0.3749827 -0.3558898 -0.4206861
Clustering vector:
69081 48683 24104 51237 6743 1329 25681 60633 3691 42341 20280 38152 14493
2 1 2 1 2 1 2 2 2 1 2 1 2
10694 863 7878 67307 59125 4019 39966 42111 58406 14026 15301 68745 52742
2 2 2 2 1 2 2 2 2 2 2 1 2
5825 58142 9526 34384 25 54498 6172 58509 31154 61361 65010 45759 67787
2 2 2 2 2 2 2 1 2 1 2 2 2
30101 46233 20657 27890 8617 14750 46684 28538 45432 19570 51795
1 1 2 2 1 2 1 1 2 2 2
Within cluster sum of squares by cluster:
[1] 93.0985 109.8310
(between_SS / total_SS = 31.0 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss"
[6] "betweenss" "size" "iter" "ifault"
Örneklemimizi ikiye ayırmış olduk. İlk küme 14, ikinci küme 36 gözlem içeriyor. Kümelerin değişken ortalamalarını, hangi gözlemin hangi kümede olduğunu ve kümelerin kareler toplamını görüyoruz.
7.3 Hiyerarşik Kümeleme
Veri noktalarınızı üst ve alt kümeler halinde kümeler. Müşterilerinizi daha genç ve daha büyük yaşlara bölebilir ve ardından bu grupların her birini kendi bireysel kümelerine de bölebilirsiniz.
Şekil 7.3: Hiyerarşik Kümeleme
Hiyerarşik kümeleme de K-Ortalamalar tekniği gibi aslında aynı sonucu hedefliyor fakat, farklı bir yöntemle, taneciklerden bütüne doğru ilerliyor. K-Ortalamalar tekniğinde olduğu gibi küme kullanıcıdan sayısını istemiyor. Uygulamaya geçelim.
Bu yöntemi uygulamak için 4 farklı tekniğimiz var. Bunlara linkage (bağlantı) metotları deniyor.
Average: Kümeler arası aritmetik ortalamayı kontrol eder.
Single: En yakın komşu ile benzerliği kontrol eder.
Complete: En uzak komşu ile benzerliği kontrol eder.
Ward: Kümeler arası kareler toplamını kontrol eder.
En iyi metotu bulmak için aşağıdaki fonksiyonu kullanacağız.
m <- c("average", "single", "complete", "ward")
names(m) <- c("average", "single", "complete", "ward")
ac <- function(x) {
agnes(dist(df, method = "euclidean"), method = x)$ac
}
map_dbl(m, ac) average single complete ward
0.7676608 0.6420281 0.8557998 0.8985124
Görüldüğü üzere “ward” en iyi çalışan metotdur.
hc <- hclust(dist(df, method = "euclidean"), method = "ward.D2")
hc
Call:
hclust(d = dist(df, method = "euclidean"), method = "ward.D2")
Cluster method : ward.D2
Distance : euclidean
Number of objects: 50
plot(hc, cex = 0.7)Ward yöntemini kullanarak analizi yaptık ve dendogramı çizdirdik. Bu ağacı nereden keseceğimize karar vereceğiz.
K-Means’de kullandığımız Elbow ve Average Silhoutte yöntemleri burada da kullanılıyor.
7.3.1 Elbow Yöntemi
- Kümeler için hata hesaplama.
fviz_nbclust(df, FUN = hcut, method = "wss")Burada ki fark “FUN=hcut” belirlenip, hiyerarşik için bu yöntemi kullandık. 2 ya da 3 uygun gözüküyor.
7.2.2 Average Silhoutte Yöntemi
- Küme içi kalite skoru hesaplama.
fviz_nbclust(df, FUN = hcut, method = "silhouette")Burada da tekrardan 2 sonucunu elde ettik. Ancak bu sefer k=3 alarak devam etmek istiyorum. Elbow da bunu destekliyor.
sub_grp <- cutree(hc, k = 3)
table(sub_grp)sub_grp
1 2 3
14 24 12
14 gözlem ilk kümeye, 24 gözlem ikinci kümeye ve 12 gözlem üçüncü kümeye ayrıldı.
fviz_cluster(list(data = df, cluster = sub_grp))Kümelerin grafiği yukarıda ki gibidir. Son olarak dendogram üzerinden gösterip bitirelim.
plot(hc, cex = 0.6)
rect.hclust(hc, k = 3, border = 2:5)Dendogram üzerinde bütün gözlemlerin hangi kümede olduğunu görebiliyoruz.
8. Özet
8.1 İşlenen Konular
8.1.1 Veriyi Keşfetmek
- Veriyi Düzenleme
- Örneklem çekme, değişken oluşturma, yeniden şekillendirme ve özetleme
- data.table
- dplyr
- sparklyr
- Veriyi Görselleştirme
- ggplot2
- cowplot
- ggExtra
- plotly
- gganimate
8.1.2 Veriyi Modelleme
- Karar Ağaçları
- Sınıflandırma
- rpart
- rpart.plot
- Rastgele Ormanlar
- Sınıflandırma
- RandomForest
- Model Oluşturma ve Değerlendirme
- modelr
- caret
- Destek Vektör Makineleri
- Destek vektör sınıflandırıcıları
- Lojistik regresyon
- Modellerin ayarlanması ve değerlendirilmesi
- e1071
Kaynaklar
https://rviews.rstudio.com/2019/07/17/3-big-data-strategies-for-r/
https://analyticsindiamag.com/6-ways-r-is-best-suited-for-big-data-analytics/
https://bookdown.org/yihui/rmarkdown/html-document.html#data-frame-printing
https://www.analyticsvidhya.com/blog/2015/07/guide-data-visualization-r/
http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html
https://rkabacoff.github.io/datavis/Data.html#HoustonCrime #verisetleri
https://web.stanford.edu/class/bios221/book/Chap-Graphics.html
https://www.machinelearningplus.com/data-manipulation/datatable-in-r-complete-guide/
https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html
https://atrebas.github.io/post/2019-03-03-datatable-dplyr/#data.table-and-dplyr
https://towardsdatascience.com/fast-transition-between-dplyr-and-data-table-c02d53cb769f
https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/data.frame
https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html
https://medium.com/t%C3%BCrkiye/makine-%C3%B6%C4%9Frenmesi-nedir-20dee450b56e
https://azure.microsoft.com/tr-tr/overview/machine-learning-algorithms/#techniques
https://www.endustri40.com/big-datanin-buyuk-veri-endustriyel-kullanimi/
https://www.yonetimdeinsan.com/data-toplum/big-data-nedir-onemli/
https://www.gtech.com.tr/big-data-buyuk-veri-analizi-nasil-yapilir/
https://www.teknolojidenbihaber.com/buyuk-veri-big-data-kullanan-13-uygulama-alani/
https://www.veribilimiokulu.com/yapay-sinir-agiartificial-neural-network-nedir/
https://medium.com/deep-learning-turkiye/ensemble-learning-bagging-ve-boosting-50643428b22b
https://devhunteryz.wordpress.com/2018/09/20/rastgele-ormanrandom-forest-algoritmasi/
https://veribilimcisi.com/2018/02/23/karar-agaclari-decision-trees/
https://www.veribilimiokulu.com/kumeleme-notlari-5-hiyerarsik-kumeleme/
https://medium.com/@altanyildiz/veri-g%C3%B6rselle%C5%9Ftirme-b32c1b65eec1
https://www.rdocumentation.org/packages/ggplot2/versions/3.3.3/topics/ggplot
https://monashbioinformaticsplatform.github.io/r-more/topics/tidyverse.html
https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/data.frame
https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html